<template>
    <div class="multi-dimensional-analysis">
        <!-- Filter Card -->
        <div class="filter-card">
            <div class="card-header">
                <span class="card-title">筛选条件</span>
                <div class="card-tools">
                    <div class="dimension-controls">
                        <div class="control-group">
                            <label>X 轴</label>
                            <el-select
                                v-model="axisMappings.x"
                                size="small"
                                class="custom-select-small"
                                style="min-width: 100px"
                            >
                                <el-option
                                    v-for="option in dimensionOptions"
                                    :key="'x-' + option.value"
                                    :label="option.label"
                                    :value="option.value"
                                    :disabled="option.value === axisMappings.y"
                                />
                            </el-select>
                        </div>

                        <div class="control-group">
                            <label>Y 轴</label>
                            <el-select
                                v-model="axisMappings.y"
                                size="small"
                                class="custom-select-small"
                                style="min-width: 100px"
                            >
                                <el-option
                                    v-for="option in dimensionOptions"
                                    :key="'y-' + option.value"
                                    :label="option.label"
                                    :value="option.value"
                                    :disabled="option.value === axisMappings.x"
                                />
                            </el-select>
                        </div>

                        <div class="control-group">
                            <label>高度</label>
                            <el-select
                                v-model="axisMappings.metric"
                                size="small"
                                class="custom-select-small"
                                style="width: 100px"
                            >
                                <el-option
                                    v-for="option in metricOptions"
                                    :key="'metric-' + option.value"
                                    :label="option.label"
                                    :value="option.value"
                                />
                            </el-select>
                        </div>
                    </div>

                    <div class="legend">
                        <span class="legend-item">
                            <i class="legend-dot" style="background-color: #409eff"></i>
                            柱体高度：{{ metricLabels[axisMappings.metric] }}
                        </span>
                        <span class="legend-item legend-item--color">
                            <i class="legend-dot gradient"></i>
                            颜色：失业率（绿低 → 红高）
                        </span>
                    </div>

                    <el-button type="primary" class="btn-primary-theme small" @click="handleQuery"
                        >查询</el-button
                    >
                </div>
            </div>

            <div class="search-section">
                <el-form :inline="true" :model="queryForm" class="filter-form">
                    <el-form-item label="调查期">
                        <el-cascader
                            v-model="queryForm.periodIds"
                            :options="periodOptions"
                            :props="{ multiple: true, emitPath: false }"
                            placeholder="请选择调查期"
                            collapse-tags
                            collapse-tags-tooltip
                            clearable
                            class="custom-select"
                            style="width: 300px"
                        />
                    </el-form-item>

                    <el-form-item label="地区">
                        <el-select
                            v-model="queryForm.regions"
                            multiple
                            filterable
                            collapse-tags
                            collapse-tags-tooltip
                            placeholder="请选择地区"
                            class="custom-select"
                            style="width: 260px"
                        >
                            <el-option
                                v-for="option in regionOptions"
                                :key="option.value"
                                :label="option.label"
                                :value="option.value"
                            />
                        </el-select>
                    </el-form-item>

                    <el-form-item label="行业">
                        <el-select
                            v-model="queryForm.industries"
                            multiple
                            filterable
                            collapse-tags
                            collapse-tags-tooltip
                            placeholder="请选择行业"
                            class="custom-select"
                            style="width: 260px"
                        >
                            <el-option
                                v-for="option in industryOptions"
                                :key="option.value"
                                :label="option.label"
                                :value="option.value"
                            />
                        </el-select>
                    </el-form-item>

                    <el-form-item label="性质">
                        <el-select
                            v-model="queryForm.natures"
                            multiple
                            filterable
                            collapse-tags
                            collapse-tags-tooltip
                            placeholder="请选择性质"
                            class="custom-select"
                            style="width: 260px"
                        >
                            <el-option
                                v-for="option in natureOptions"
                                :key="option.value"
                                :label="option.label"
                                :value="option.value"
                            />
                        </el-select>
                    </el-form-item>
                </el-form>
            </div>
        </div>

        <!-- Visualization Card -->
        <div class="visualization-card">
            <div class="card-header">
                <span class="card-title">
                    3D 多维数据可视化
                    <small class="mapping-desc">
                        （X：{{ dimensionLabels[axisMappings.x] }}，Y：{{
                            dimensionLabels[axisMappings.y]
                        }}）
                    </small>
                </span>
            </div>

            <div class="chart-wrapper">
                <div ref="chartContainer" class="chart-container"></div>

                <div v-if="loading" class="loading-overlay">
                    <el-icon class="is-loading" :size="40">
                        <Loading />
                    </el-icon>
                    <p>正在加载数据...</p>
                </div>

                <div v-if="!loading && dataPoints.length === 0" class="empty-state">
                    <el-empty description="暂无数据，请选择筛选条件后查询" />
                </div>
            </div>
        </div>

        <!-- Table Card -->
        <div v-if="dataPoints.length > 0" class="table-card">
            <div class="card-header">
                <span class="card-title">
                    数据详情
                    <small class="sub-title"
                        >（共 {{ dataPoints.length }} 个数据点 — 当前指标：{{
                            metricLabels[axisMappings.metric]
                        }}）</small
                    >
                </span>
            </div>

            <div
                class="table-scroll"
                v-infinite-scroll="loadMore"
                :infinite-scroll-disabled="infiniteDisabled"
                :infinite-scroll-distance="80"
                :infinite-scroll-immediate="false"
            >
                <el-table
                    :data="displayRows"
                    class="modern-table"
                    :header-cell-style="{
                        background: '#f8fafc',
                        color: '#475569',
                        fontWeight: '700',
                        fontSize: '13px',
                        height: '50px',
                    }"
                    :cell-style="{ padding: '8px 0' }"
                >
                    <el-table-column prop="periodLabel" label="调查期" width="160" />
                    <el-table-column prop="regionName" label="地区" width="160" />
                    <el-table-column prop="industryName" label="行业" min-width="220" />
                    <el-table-column prop="natureName" label="性质" width="160" />
                    <el-table-column
                        prop="constructionEmployed"
                        label="建档期人数"
                        width="160"
                        align="right"
                    >
                        <template #default="{ row }">
                            {{ formatInteger(row.constructionEmployed) }}
                        </template>
                    </el-table-column>
                    <el-table-column
                        prop="totalEmployed"
                        label="调查期人数"
                        width="160"
                        align="right"
                    >
                        <template #default="{ row }">
                            {{ formatInteger(row.totalEmployed) }}
                        </template>
                    </el-table-column>
                    <el-table-column
                        prop="totalUnemployed"
                        label="失业人数变化"
                        width="160"
                        align="right"
                    >
                        <template #default="{ row }">
                            {{ formatInteger(row.totalUnemployed) }}
                        </template>
                    </el-table-column>
                    <el-table-column
                        prop="selectedMetric"
                        :label="`${metricLabels[axisMappings.metric]}`"
                        width="200"
                        align="right"
                    >
                        <template #default="{ row }">
                            <span class="metric-value">{{
                                formatInteger(row.selectedMetric)
                            }}</span>
                        </template>
                    </el-table-column>
                    <el-table-column
                        prop="unemploymentRate"
                        label="失业率 (%)"
                        width="140"
                        align="right"
                    >
                        <template #default="{ row }">
                            <el-tag
                                :type="getUnemploymentRateType(row.unemploymentRate)"
                                effect="dark"
                                round
                                size="small"
                            >
                                {{ row.unemploymentRate }}%
                            </el-tag>
                        </template>
                    </el-table-column>
                </el-table>
                <div class="scroll-status">
                    <span v-if="infiniteDisabled">已展示全部 {{ dataPoints.length }} 条记录</span>
                    <span v-else>下滑加载更多…</span>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
import * as echarts from 'echarts';
import 'echarts-gl';
import { ElMessage } from 'element-plus';
import { Loading } from '@element-plus/icons-vue';
import { getMultiDimensionalAnalysis } from '@/api/dataAnalysis.js';
import periodApi from '@/api/period';
import regionData from '@/dict/yunnan_region_code.json';
import enterpriseTypeData from '@/dict/enterprise_type.json';
import enterpriseIndustryData from '@/dict/enterprise_industry.json';

// ... (script logic remains exactly the same) ...
const queryForm = reactive({
    periodIds: [],
    regions: [],
    industries: [],
    natures: [],
});

const dimensionOptions = [
    { label: '地区', value: 'region' },
    { label: '行业', value: 'industry' },
    { label: '性质', value: 'nature' },
];

const metricOptions = [
    { label: '企业数', value: 'enterpriseCount' },
    { label: '岗位数', value: 'totalEmployed' },
];

const dimensionLabels = {
    region: '地区',
    industry: '行业',
    nature: '性质',
};

const metricLabels = {
    enterpriseCount: '企业数',
    totalEmployed: '岗位数',
    totalUnemployed: '失业人数',
};

const axisMappings = reactive({
    x: 'region',
    y: 'industry',
    metric: 'enterpriseCount',
});

const periodList = ref([]);

const periodOptions = computed(() => {
    const groups = {};

    periodList.value.forEach((period) => {
        const name = period.investigateTime || '';
        const yearMatch = name.match(/^(\d{4})/);
        const year = yearMatch ? yearMatch[1] : '其他';

        if (!groups[year]) {
            groups[year] = [];
        }

        let monthLabel = name;
        if (year !== '其他') {
            monthLabel = name.replace(year, '').replace(/^[年-]/, '');
        }

        groups[year].push({
            value: period.periodId,
            label: monthLabel,
        });
    });

    return Object.keys(groups)
        .sort((a, b) => b.localeCompare(a))
        .map((year) => ({
            value: year,
            label: year === '其他' ? '其他' : `${year}年`,
            children: groups[year],
        }));
});

const dataPoints = ref([]);
const loading = ref(false);

const chartContainer = ref(null);
let chartInstance = null;

const INITIAL_BATCH_SIZE = 30;
const displayCount = ref(INITIAL_BATCH_SIZE);

const displayRows = computed(() => {
    const slice = dataPoints.value.slice(0, displayCount.value);
    return slice.map((row) => ({
        ...row,
        selectedMetric: parseNumber(row[axisMappings.metric]),
    }));
});

const infiniteDisabled = computed(() => displayCount.value >= dataPoints.value.length);

const loadMore = () => {
    if (infiniteDisabled.value) return;
    displayCount.value = Math.min(displayCount.value + INITIAL_BATCH_SIZE, dataPoints.value.length);
};

const resetDisplayCount = () => {
    displayCount.value = Math.min(
        INITIAL_BATCH_SIZE,
        dataPoints.value.length || INITIAL_BATCH_SIZE
    );
};

const loadPeriodList = async () => {
    try {
        const response = await periodApi.getPeriodList({ pageSize: 1000 });
        if (response.status === 'success') {
            periodList.value = (response.data.list || []).sort(
                (a, b) => new Date(b.investigateTime) - new Date(a.investigateTime)
            );
        }
    } catch (error) {
        console.error('加载调查期列表失败:', error);
        ElMessage.error('加载调查期列表失败');
    }
};

const parseNumber = (value, fallback = 0) => {
    const num = Number(value);
    return Number.isFinite(num) ? num : fallback;
};

// 因为录入数据库的时候，逻辑写反了 这边需要将失业人数的正反值进行互换
const normalizeNonNegative = (raw, fallback = 0) => {
    const num = parseNumber(raw, fallback);
    if (!Number.isFinite(num)) return fallback;
    return num === 0 ? 0 : -num;
};

// 这个是处理下拉选择的选项
const normalizeOptionValue = (code) => {
    const parsed = Number(code);
    return Number.isFinite(parsed) ? parsed : code;
};

const createTopLevelOptions = (list = []) =>
    (Array.isArray(list) ? list : [])
        .filter((item) => item && (item.parentId == null || item.parentId === 0))
        .map((item) => ({
            label: item.name.replace(/^[A-Z]\.\s*/, ''), // strip “A.”, “B.” pr～efixes in行业字典
            value: normalizeOptionValue(item.code),
        }));

const regionOptions = computed(() => createTopLevelOptions(regionData));
const industryOptions = computed(() => createTopLevelOptions(enterpriseIndustryData));
const natureOptions = computed(() => createTopLevelOptions(enterpriseTypeData));

function parseInvestigateTime(value) {
    if (!value) return null;
    if (typeof value === 'number') {
        return value;
    }

    const normalized = value
        .toString()
        .replace(/年|\//g, '-')
        .replace(/月/g, '')
        .replace(/日/g, '');

    const withDay =
        normalized.length === 7 && normalized.indexOf('-') === 4 ? `${normalized}-01` : normalized;

    const date = new Date(withDay);
    if (!Number.isNaN(date.getTime())) {
        return date.getTime();
    }

    const digits = value.toString().replace(/[^0-9]/g, '');
    return digits ? Number(digits) : null;
}

const transformDataPoints = (rawList = []) => {
    const dict = new Map();
    periodList.value.forEach((period) => {
        const sortValue =
            parseInvestigateTime(period.investigateTime) ?? Number(period.periodId) ?? 0;
        dict.set(period.periodId, {
            label: period.investigateTime || `调查期 ${period.periodId}`,
            sortValue,
        });
    });

    const selectedPeriodIds = Array.isArray(queryForm.periodIds) ? [...queryForm.periodIds] : [];
    const fallbackSinglePeriodId = selectedPeriodIds.length === 1 ? selectedPeriodIds[0] : null;
    const fallbackSingleLabel =
        fallbackSinglePeriodId != null
            ? (dict.get(fallbackSinglePeriodId)?.label ?? `调查期 ${fallbackSinglePeriodId}`)
            : null;
    const multiPeriodLabel = selectedPeriodIds.length > 1 ? '多期汇总' : '未指定调查期';

    return rawList.map((item, index) => {
        let periodId = item.periodId ?? item.period_id ?? null;
        if (periodId == null && fallbackSinglePeriodId != null) {
            periodId = fallbackSinglePeriodId;
        }

        const periodInfo = periodId != null ? dict.get(periodId) : null;
        const enterpriseCount = parseNumber(item.enterpriseCount ?? item.enterprise_count);
        const constructionEmployed = parseNumber(
            item.constructionEmployed ??
                item.construction_employed ??
                item.totalConstructionEmployed ??
                item.total_construction_employed
        );
        const totalEmployed = parseNumber(item.totalEmployed ?? item.total_employed);
        const totalUnemployed = normalizeNonNegative(item.totalUnemployed ?? item.total_unemployed);
        const unemployment = parseNumber(item.unemploymentRate ?? item.unemployment_rate);

        const resolvedPeriodLabel =
            periodInfo?.label ??
            (periodId != null ? `调查期 ${periodId}` : (fallbackSingleLabel ?? multiPeriodLabel));
        const resolvedPeriodSortValue =
            periodInfo?.sortValue ??
            (periodId != null ? Number(periodId) || index : (fallbackSinglePeriodId ?? index));

        return {
            ...item,
            periodId,
            periodLabel: resolvedPeriodLabel,
            periodSortValue: resolvedPeriodSortValue,
            regionCode: parseNumber(item.regionCode ?? item.region_code),
            regionName: item.regionName ?? item.region_name ?? '未知地区',
            industryCode: parseNumber(item.industryCode ?? item.industry_code),
            industryName: item.industryName ?? item.industry_name ?? '未知行业',
            natureCode: parseNumber(item.natureCode ?? item.nature_code),
            natureName: item.natureName ?? item.nature_name ?? '未知性质',
            enterpriseCount,
            constructionEmployed,
            totalEmployed,
            totalUnemployed,
            unemploymentRate:
                Number(unemployment.toFixed ? unemployment.toFixed(2) : unemployment) || 0,
        };
    });
};

const handleQuery = async () => {
    loading.value = true;

    try {
        const response = await getMultiDimensionalAnalysis(queryForm);

        if (response.status === 'success' && response.data) {
            const transformed = transformDataPoints(response.data);
            dataPoints.value = transformed;
            resetDisplayCount();
            ElMessage.success(`查询成功，共 ${transformed.length} 个数据点`);
            await nextTick();
            renderChart();
        } else {
            ElMessage.warning('未查询到数据');
            dataPoints.value = [];
            resetDisplayCount();
            disposeChart();
        }
    } catch (error) {
        console.error('查询失败:', error);
        ElMessage.error('查询失败: ' + (error.message || '网络错误'));
        dataPoints.value = [];
        resetDisplayCount();
        disposeChart();
    } finally {
        loading.value = false;
    }
};

const rateToColor = (rate) => {
    if (rate < 2) return '#67C23A';
    if (rate < 4) return '#409EFF';
    if (rate < 6) return '#E6A23C';
    return '#F56C6C';
};

const formatInteger = (value) => {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed.toLocaleString() : '-';
};

const formatTooltipMetric = (value) => {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed.toLocaleString() : '0';
};

const disposeChart = () => {
    if (chartInstance) {
        chartInstance.dispose();
        chartInstance = null;
    }
};

const renderChart = () => {
    if (!chartContainer.value) return;

    if (!chartInstance) {
        chartInstance = echarts.init(chartContainer.value);
    }

    const rows = dataPoints.value;
    if (!rows || rows.length === 0) {
        chartInstance.clear();
        return;
    }

    const regionMeta = new Map();
    const industryMeta = new Map();
    const natureMeta = new Map();
    const periodMeta = new Map();

    const getIndex = (map, raw) => {
        const key = raw ?? 'ALL';
        if (!map.has(key)) {
            map.set(key, map.size);
        }
        return map.get(key);
    };

    const registerMeta = (metaMap, key, index, label, fallback) => {
        const safeKey = key ?? 'ALL';
        if (!metaMap.has(safeKey)) {
            metaMap.set(safeKey, { code: safeKey, index, label: label || fallback });
        }
    };

    const processed = rows.map((item, idx) => {
        const periodIndex = getIndex(periodMeta, item.periodId);
        const regionIndex = getIndex(regionMeta, item.regionCode);
        const industryIndex = getIndex(industryMeta, item.industryCode);
        const natureIndex = getIndex(natureMeta, item.natureCode);

        registerMeta(periodMeta, item.periodId, periodIndex, item.periodLabel, '调查期');
        registerMeta(regionMeta, item.regionCode, regionIndex, item.regionName, '地区');
        registerMeta(industryMeta, item.industryCode, industryIndex, item.industryName, '行业');
        registerMeta(natureMeta, item.natureCode, natureIndex, item.natureName, '性质');

        return {
            ...item,
            periodIndex,
            regionIndex,
            industryIndex,
            natureIndex,
        };
    });

    const dimensionIndexResolvers = {
        region: (item) => item.regionIndex,
        industry: (item) => item.industryIndex,
        nature: (item) => item.natureIndex,
    };

    const getDimensionLabel = (item, dim) => {
        if (dim === 'region') return item.regionName;
        if (dim === 'industry') return item.industryName;
        return item.natureName;
    };

    const xDim = axisMappings.x;
    const yDim = axisMappings.y;
    const metricKey = axisMappings.metric;

    const aggregator = new Map();
    processed.forEach((item) => {
        const xIndex = dimensionIndexResolvers[xDim](item);
        const yIndex = dimensionIndexResolvers[yDim](item);
        const xLabel = getDimensionLabel(item, xDim);
        const yLabel = getDimensionLabel(item, yDim);

        const key = `${xIndex}-${yIndex}`;
        if (!aggregator.has(key)) {
            aggregator.set(key, {
                x: xIndex,
                y: yIndex,
                xLabel,
                yLabel,
                value: 0,
                unemployment: [],
                details: [],
            });
        }
        const entry = aggregator.get(key);
        entry.value += parseNumber(item[metricKey]);
        entry.unemployment.push(item.unemploymentRate);
        entry.details.push(item);
    });

    const xLabels = [];
    const yLabels = [];
    aggregator.forEach((entry) => {
        if (!xLabels[entry.x]) {
            xLabels[entry.x] = entry.xLabel;
        }
        if (!yLabels[entry.y]) {
            yLabels[entry.y] = entry.yLabel;
        }
    });

    const seriesData = Array.from(aggregator.values()).map((entry) => {
        const avgUnemployment = entry.unemployment.length
            ? entry.unemployment.reduce((sum, rate) => sum + rate, 0) / entry.unemployment.length
            : 0;

        const tooltipLines = [
            `${dimensionLabels[xDim]}：${entry.xLabel}`,
            `${dimensionLabels[yDim]}：${entry.yLabel}`,
            `${metricLabels[metricKey]}：${formatTooltipMetric(entry.value)}`,
            `平均失业率：${avgUnemployment.toFixed(2)}%`,
            '—— 明细 ——',
            ...entry.details.map((detail) => {
                return [
                    `调查期：${detail.periodLabel}`,
                    `地区：${detail.regionName}`,
                    `行业：${detail.industryName}`,
                    `性质：${detail.natureName}`,
                    `建档期人数：${formatTooltipMetric(detail.constructionEmployed)}`,
                    `调查期人数：${formatTooltipMetric(detail.totalEmployed)}`,
                    `失业人数：${formatTooltipMetric(detail.totalUnemployed)}`,
                    `失业率：${detail.unemploymentRate}%`,
                ].join('，');
            }),
        ];

        return {
            value: [entry.x, entry.y, entry.value],
            itemStyle: {
                color: rateToColor(avgUnemployment),
            },
            tooltip: tooltipLines.join('<br>'),
        };
    });

    const option = {
        tooltip: {
            formatter: (params) => params.data?.tooltip ?? '',
        },
        grid3D: {
            boxWidth: 260,
            boxDepth: 200,
            boxHeight: 100,
            light: {
                main: {
                    intensity: 1.2,
                    shadow: true,
                },
                ambient: {
                    intensity: 0.4,
                },
            },
            viewControl: {
                alpha: 24,
                beta: 40,
                minBeta: -10,
                maxBeta: 70,
                distance: 260,
                center: [0, 0, 0],
            },
        },
        xAxis3D: {
            type: 'category',
            name: dimensionLabels[xDim],
            data: xLabels,
            axisLabel: {
                rotate: 45,
                interval: 0,
                fontSize: 11,
                margin: 12,
            },
        },
        yAxis3D: {
            type: 'category',
            name: dimensionLabels[yDim],
            data: yLabels,
            axisLabel: {
                rotate: 45,
                interval: 0,
                fontSize: 11,
                margin: 12,
            },
        },
        zAxis3D: {
            type: 'value',
            name: metricLabels[metricKey],
            axisLabel: {
                fontSize: 11,
            },
        },
        series: [
            {
                type: 'bar3D',
                data: seriesData,
                shading: 'lambert',
                label: {
                    show: true,
                    formatter: ({ value }) => formatTooltipMetric(value[2]),
                    fontSize: 10,
                    fontWeight: 'bold',
                    color: '#333',
                },
                emphasis: {
                    label: {
                        show: true,
                        fontSize: 12,
                        fontWeight: 'bold',
                        color: '#fff',
                    },
                },
            },
        ],
    };

    chartInstance.setOption(option);
};

const getUnemploymentRateType = (rate) => {
    if (rate < 2) return 'success';
    if (rate < 4) return 'primary';
    if (rate < 6) return 'warning';
    return 'danger';
};

onMounted(async () => {
    await loadPeriodList();
});

onUnmounted(() => {
    disposeChart();
});

watch(
    () => ({ ...axisMappings }),
    async () => {
        if (dataPoints.value.length > 0) {
            await nextTick();
            renderChart();
        }
    },
    { deep: true }
);

watch(dataPoints, async (newData) => {
    resetDisplayCount();
    if (newData.length > 0) {
        await nextTick();
        renderChart();
    } else {
        disposeChart();
    }
});
</script>

<style scoped lang="scss">
.multi-dimensional-analysis {
    /* Filter Card */
    .filter-card {
        background: #ffffff;
        border-radius: 16px;
        box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.02);
        margin-bottom: 24px;
        border: 1px solid rgba(241, 245, 249, 1);
        overflow: hidden;
    }

    .card-header {
        padding: 16px 24px;
        border-bottom: 1px solid #f1f5f9;
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: #fafafa;
    }

    .card-title {
        font-size: 15px;
        font-weight: 700;
        color: #0f172a;
    }

    .card-tools {
        display: flex;
        align-items: center;
        gap: 20px;
    }

    .dimension-controls {
        display: flex;
        align-items: center;
        gap: 16px;
    }

    .control-group {
        display: flex;
        align-items: center;
        gap: 8px;

        label {
            font-size: 12px;
            color: #64748b;
            font-weight: 600;
        }
    }

    .legend {
        display: flex;
        gap: 12px;

        .legend-item {
            display: flex;
            align-items: center;
            font-size: 12px;
            color: #64748b;

            .legend-dot {
                width: 8px;
                height: 8px;
                border-radius: 50%;
                margin-right: 6px;

                &.gradient {
                    width: 40px;
                    height: 6px;
                    border-radius: 3px;
                    background: linear-gradient(90deg, #67c23a, #409eff, #e6a23c, #f56c6c);
                }
            }
        }
    }

    .search-section {
        padding: 20px 24px;
    }

    .filter-form {
        margin-bottom: 0;
        :deep(.el-form-item) {
            margin-bottom: 0;
            margin-right: 24px;
        }
    }

    /* Visualization Card */
    .visualization-card,
    .table-card {
        background: #ffffff;
        border-radius: 24px;
        box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.03);
        border: 1px solid rgba(241, 245, 249, 1);
        margin-bottom: 24px;
        overflow: hidden;
    }

    .mapping-desc {
        font-size: 12px;
        color: #94a3b8;
        font-weight: 400;
        margin-left: 8px;
    }

    .chart-wrapper {
        padding: 24px;
        position: relative;
    }

    .chart-container {
        width: 100%;
        height: 600px;
        background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
        border-radius: 16px;
        border: 1px solid #f1f5f9;
    }

    .loading-overlay {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
        color: #94a3b8;

        p {
            margin-top: 12px;
            font-size: 14px;
        }
    }

    .empty-state {
        padding: 60px 0;
    }

    /* Table Styles */
    .table-scroll {
        max-height: 600px;
        overflow-y: auto;
    }

    .sub-title {
        font-weight: 400;
        font-size: 13px;
        color: #64748b;
        margin-left: 8px;
    }

    .modern-table {
        --el-table-border-color: #f1f5f9;
        --el-table-row-hover-bg-color: #f8fafc;
        --el-table-header-bg-color: #f8fafc;
    }

    .metric-value {
        font-weight: 700;
        font-family: 'JetBrains Mono', monospace;
        color: #0f172a;
    }

    .scroll-status {
        text-align: center;
        padding: 16px 0;
        font-size: 12px;
        color: #94a3b8;
        border-top: 1px solid #f1f5f9;
    }

    /* Inputs & Buttons */
    .custom-select,
    .custom-select-small {
        :deep(.el-input__wrapper) {
            border-radius: 8px;
            box-shadow: 0 0 0 1px #e2e8f0 inset;
            padding: 6px 12px;
            &.is-focus {
                box-shadow: 0 0 0 2px #818cf8 inset;
            }
        }
    }

    .custom-select-small {
        min-width: 40px;
        :deep(.el-input__wrapper) {
            padding: 2px 8px;
            height: 28px;
        }
    }

    .btn-primary-theme {
        background: linear-gradient(135deg, #4f46e5 0%, #6366f1 100%);
        border: none;
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(79, 70, 229, 0.2);
        transition: all 0.2s;
        font-weight: 600;

        &.small {
            padding: 6px 16px;
            font-size: 13px;
        }

        &:hover {
            transform: translateY(-1px);
            box-shadow: 0 8px 20px rgba(79, 70, 229, 0.3);
        }
    }
}
</style>
